<template>
  <div>
    <div class="handel-header">
      <crm-relative
        v-if="viewLoaded"
        ref="crmrelative"
        :visible.sync="showSelectView"
        :radio="false"
        :selected-data="{ product: productList || [] }"
        :props="relativeProps"
        data-type="product"
        @changeCheckout="selectInfos" />
      <el-button
        v-if="!disabled"
        type="primary"
        @click="addClick">{{ $t('crm.product.310670cd94f99c14a9203e2bd85f3538') }}</el-button>
    </div>
    <el-table
      v-loading="loading"
      :data="productList"
      style="width: 100%;">
      <el-table-column
        v-for="(item, index) in fieldList"
        :key="index"
        :prop="item.fieldName"
        :min-width="['salesPrice','productNum','discount','relatedRemark'].includes(item.fieldName) ? 150 : 100"
        show-overflow-tooltip
        :label="item.name">
        <template slot-scope="scope">
          <el-input
            v-if="item.fieldName === 'salesPrice'"
            v-model="scope.row.salesPrice"
            v-wk-number
            :placeholder="$t('crm.product.98953a08659ed3f735c648a64f51f07f')"
            type="number"
            :disabled="disabled"
            @input="salesPriceChange(scope)" />

          <el-input
            v-else-if="item.fieldName === 'productNum'"
            v-model="scope.row.productNum"
            v-wk-number
            type="number"
            :placeholder="$t('crm.product.e3c398bde7f23947d43ab132c7ab104e')"
            :disabled="disabled"
            @input="numChange(scope)" />

          <el-input
            v-else-if="item.fieldName === 'discount'"
            v-model="scope.row.discount"
            v-wk-number
            :placeholder="$t('crm.product.4fd343b8419d4c79ff41ce5a2574249b')"
            type="number"
            :disabled="disabled"
            @input="discountChange(scope)" />

          <el-input
            v-else-if="item.fieldName === 'relatedRemark'"
            v-model="scope.row.relatedRemark"
            :placeholder="$t('crm.product.4fd343b8419d4c79ff41ce5a2574249b')"
            type="text"
            :disabled="disabled" />

          <wk-field-view
            v-else
            :props="item"
            :form-type="item.formType"
            :value="scope.row[scope.column.property]"
            :ignore-fields="['settingName']">
            {{ fieldFormatter(scope.row, scope.column, scope.row[scope.column.property], item) }}
          </wk-field-view>

          <!-- <wk-picture-preview
            v-else-if="item.formType === 'pic'"
            :picture-url="scope.row[item.fieldName]" />

          <span v-else>{{ scope.row[item.fieldName] }}</span> -->
        </template>
      </el-table-column>
      <el-table-column :label="$t('crm.product.51615da1a3eabe98319ebd1c2e65da16')">
        <template slot-scope="scope">
          <el-button :disabled="disabled" type="primary-text" style="padding: 0;" @click="removeItem(scope.$index)">{{ $t('crm.product.849eb5f00257818ddbb5bd75fc9c72b6') }}</el-button>
        </template>
      </el-table-column>
    </el-table>
    <flexbox class="handle-footer">
      <template v-if="showDiscountRate">
        <div class="discount-title">{{ $t('crm.product.f92f28ef5e913d412659275383f19c10') }}</div>
        <el-input
          v-model="discountRate"
          v-wk-number
          style="width: 80px;"
          :placeholder="$t('crm.product.4c134c0c6987b9a9c40824c49079aea3')"
          type="number"
          :disabled="disabled"
          @input="rateChange" />
      </template>
      <div class="total-info discount-title">{{ $t('crm.product.3f966bb369efd301e58fc2bc4792cc5b') }}
        <span class="info-yellow">{{ productList.length }}</span>种
        <template v-if="showTotalPrice">
          总金额：
          <el-input
            v-model="totalPrice"
            v-wk-number
            style="width: 120px;margin-right: 4px;"
            :placeholder="$t('crm.product.9848410502d2428e660acf98abb22619')"
            type="number"
            :disabled="disabled"
            @input="totalPriceChange"
            @blur="totalPrice || (totalPrice = 0)" />{{ $t('crm.product.99dd5f71d033b3c084d1d181083b021f') }}
        </template>
      </div>
    </flexbox>
  </div>
</template>

<script type="text/javascript">
import { crmRelativeProductListHeadAPI } from '@/api/crm/common'
import ObjMixin from './ObjMixin'
import CrmRelative from '@/components/CreateCom/CrmRelative'
import WkFieldView from '@/components/NewCom/WkForm/WkFieldView'
import { getFormFieldShowName } from '@/components/NewCom/WkForm/utils'
import NP from 'number-precision'
import { objDeepCopy } from '@/utils'
import { isArray } from '@/utils/types'
import { debounce } from 'throttle-debounce'

export default {
  name: 'XhProduct', // 关联产品
  components: {
    CrmRelative,
    WkFieldView
  },
  mixins: [ObjMixin],
  props: {},
  data() {
    return {
      showSelectView: false, // 内容
      viewLoaded: false,
      loading: false,
      fieldList: [],
      productList: [],
      totalPrice: 0,
      discountRate: '',

      calcField: ['salesPrice', 'productNum', 'discount', 'subtotal'],
      showDiscountRate: false,
      showTotalPrice: false,
      ignoreChange: false // 从外部修改的时候，不触发change事件
    }
  },
  computed: {
    // 产品弹框配置项
    relativeProps() {
      return {
        mainTableProps: {
          showScene: false,
          ignoreFilterFields: ['status']
        },
        params: {
          searchList: [{
            formType: 'select',
            name: 'status',
            type: 1,
            values: [1]
          }]
        }
      }
    }
  },
  watch: {
    dataValue: function(value) {
      this.debounceRefreshProductList()
    }
  },
  created() {
    this.debounceRefreshProductList = debounce(500, this.refreshProductList)
    this.debounceRefreshProductList()
  },
  methods: {
    /**
     * @description: 比较两个产品是否一致
     * @param {*} newProduct
     * @param {*} oldProduct
     * @return {*}
     */
    compareProductList(newProduct, oldProduct) {
      if (!isArray(newProduct) || !isArray(oldProduct)) return false
      if (newProduct.length !== oldProduct.length) return false
      for (let index = 0; index < newProduct.length; index++) {
        const element = newProduct[index]
        const hasProduct = oldProduct.find(item => item.productId === element.productId)
        if (!hasProduct) return false
        if (element.salesPrice != hasProduct.salesPrice ||
        element.productNum != hasProduct.productNum ||
        element.discount != hasProduct.discount ||
        element.relatedRemark != hasProduct.relatedRemark) {
          return false
        }
      }
      return true
    },

    /**
     * @description: 获取表头列表
     * @return {*}
     */
    getFieldList() {
      return new Promise((resolve, inject) => {
        this.loading = true
        crmRelativeProductListHeadAPI().then(res => {
          const fieldList = res.data || []
          const newFieldList = []
          fieldList.forEach(item => {
            if (['discountRate', 'totalPrice'].includes(item.fieldName)) {
              if (item.fieldName === 'discountRate') {
                this.showDiscountRate = true
              } else if (item.fieldName === 'totalPrice') {
                this.showTotalPrice = true
              }
            } else {
              newFieldList.push(item)
            }
          })
          this.fieldList = newFieldList
          this.updateProductList()
          this.addHideFieldToProductList(this.productList)
          this.loading = false
          resolve()
        }).catch(() => {
          this.loading = false
          inject()
        })
      })
    },

    /**
     * 刷新数据
     */
    refreshProductList() {
      this.ignoreChange = true
      if (this.fieldList.length) {
        this.updateProductList()
        this.ignoreChange = false
      } else {
        this.getFieldList().then(() => {
          this.ignoreChange = false
        }).catch(() => {
          this.ignoreChange = false
        })
      }
    },

    /**
     * @description: 通过dataValue传入数据更新产品值
     * @return {*}
     */
    updateProductList() {
      if (!this.compareProductList(this.productList, this.dataValue.product)) {
        const copyDataValue = objDeepCopy(this.dataValue)
        this.addHideFieldToProductList(copyDataValue.product || [])
        this.productList = copyDataValue.product || []
        this.totalPrice = copyDataValue.totalPrice || 0
        this.discountRate = copyDataValue.discountRate || ''
      }
    },

    /**
     * @description: 特殊字段隐藏赋予初始值
     * @return {*}
     */
    addHideFieldToProductList(productList) {
      const noIncludesField = []
      for (const item of this.calcField) {
        const result = this.includesField(this.fieldList, item)
        if (!result) {
          noIncludesField.push(item)
        }
      }

      productList = productList.map(item => {
        for (const sitem of noIncludesField) {
          if (sitem === 'productNum') {
            if (item[sitem] != 1) {
              item[sitem] = 1 // 数量默认值为1，其他默认值为0
            }
          } else {
            if (item[sitem] != 0) {
              item[sitem] = 0
            }
          }
        }
        return item
      })
    },

    /**
     * @description: 是否包含某个字段
     * @param {*} list
     * @param {*} fieldName
     * @return {*}
     */
    includesField(list, fieldName) {
      const result = list.find(item => item.fieldName === fieldName)
      if (result) {
        return true
      }
      return false
    },

    /**
     * 格式化字段
     * @param {*} row
     * @param {*} column
     * @param {*} cellValue
     */
    fieldFormatter(row, column, cellValue, field) {
      // 如果需要格式化
      if (field) {
        return getFormFieldShowName(field.formType, row[column.property], '--', field)
      }
      return row[column.property] === '' || row[column.property] === null ? '--' : row[column.property]
    },

    /**
     * 选中
     */
    selectInfos(data) {
      if (data.data) {
        const newSelects = []
        data.data.forEach(element => {
          const obj = this.productList.find(item => {
            return item.productId == element.productId
          })

          if (obj) {
            newSelects.push(obj)
          } else {
            newSelects.push(this.getShowItem(element))
          }
        })
        this.addHideFieldToProductList(newSelects)
        this.productList = newSelects
        this.calculateToal()
      }
    },

    /**
     * @description: 根据勾选数据得到默认项
     * @param {*} data
     * @return {*}
     */
    getShowItem(data) {
      const item = { ...data }
      item.name = data.name
      item.categoryName = data.categoryName
      item.unit = data.unit
      item.price = data.price || 0
      item.salesPrice = data.price || 0
      item.productNum = 1
      item.discount = 0
      item.subtotal = data.price || 0
      item.productId = data.productId
      return item
    },

    /**
     * 单价
     */
    salesPriceChange(data) {
      const item = data.row
      if (item.price !== 0) {
        let discount = NP.times(NP.divide(NP.minus(item.price, item.salesPrice || 0), item.price), 100.0)
        discount = discount.toFixed(2)
        if (item.discount !== discount) {
          item.discount = discount
        }
      }

      this.calculateSubTotal(item)
      this.calculateToal()
    },

    /**
     * 数量
     */
    numChange(data) {
      const item = data.row
      // 数量不能小于0
      if (item.productNum < 0) {
        item.productNum = 0
      }
      this.calculateSubTotal(item)
      this.calculateToal()
    },

    /**
     * 折扣
     */
    discountChange(data) {
      const item = data.row
      let salesPrice = NP.divide(NP.times(item.price, NP.minus(100.0, parseFloat(item.discount || 0))), 100.0)
      salesPrice = salesPrice.toFixed(2)
      if (item.salesPrice !== salesPrice) {
        item.salesPrice = salesPrice
      }
      this.calculateSubTotal(item)
      this.calculateToal()
    },

    /**
     * 计算单价
     */
    calculateSubTotal(item) {
      item.subtotal = NP.times(item.salesPrice, parseFloat(item.productNum || 0)).toFixed(2)
    },

    /**
     * @description: 计算总价
     * @return {*}
     */
    calcTotalPrice() {
      let totalPrice = this.getProductTotal()
      totalPrice = NP.divide(NP.times(totalPrice, 100.0 - parseFloat(this.discountRate || 0)), 100.0)
      this.totalPrice = totalPrice.toFixed(2)
    },

    /**
     * 计算总价并更新
     */
    calculateToal() {
      this.calcTotalPrice()
      this.updateValue() // 传递数据给父组件
    },

    /**
     * 获取产品总价(未折扣)
     */
    getProductTotal() {
      let totalPrice = 0.0
      for (let i = 0; i < this.productList.length; i++) {
        const item = this.productList[i]
        totalPrice = NP.plus(totalPrice, parseFloat(item.subtotal))
      }
      return totalPrice
    },

    /**
     * 总折扣
     */
    rateChange() {
      this.calculateToal()
    },

    /**
     * 总价更改 折扣更改
     */
    totalPriceChange() {
      const totalPrice = this.getProductTotal()
      if (totalPrice) {
        this.discountRate = (
          100.0 -
          NP.times(NP.divide(parseFloat(this.totalPrice), totalPrice), 100)
        ).toFixed(2)
      }
      this.updateValue()
    },

    /**
     * 删除操作
     */
    removeItem(index) {
      const removeItem = this.productList.splice(index, 1)
      // 重置勾选
      if (this.$refs.crmrelative && removeItem.length > 0) {
        this.$refs.crmrelative.toggleRowSelection('productId', removeItem[0].productId, false)
      }
      this.calculateToal()
    },

    /**
     * 更新值
     */
    updateValue() {
      if (this.ignoreChange) return
      this.valueChange({
        product: this.productList,
        totalPrice: this.totalPrice,
        discountRate: this.discountRate
      })
    },

    /**
     * 添加click
     */
    addClick() {
      this.viewLoaded = true
      this.showSelectView = true
    }
  }
}
</script>

<style lang="scss" scoped>
.handel-header {
  overflow: hidden;
  text-align: right;

  button {
    margin-bottom: 10px;
  }
}

.handle-footer {
  position: relative;
  padding-top: #{$--interval-base * 2};

  .discount-title {
    color: $--color-text-secondary;
  }

  .ellipsis-width {
    display: inline-block;
    max-width: 160px;
    vertical-align: bottom;
  }

  .discount-title-value {
    color: $--color-text-primary;
  }

  .total-info {
    position: absolute;
    top: #{$--interval-base * 2};
    right: 0;

    .info-yellow {
      margin-right: 4px;
      color: $--color-danger;
    }
  }
}
</style>
